package rest

import (
	"gcp-api-proxy/internal/conf"
	// dao "gsc-datasets/internal/db/dao"
	"net/http"
	"time"
	// "gcp-api-proxy/internal/proxys"
	"gcp-api-proxy/internal/rest/routers"
	nlpRoute "gcp-api-proxy/internal/rest/routers/nlp"
	"gcp-api-proxy/pkg/util"
	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"
	"github.com/go-chi/cors"
	"github.com/go-chi/render"
	"go.uber.org/zap"
)

type RestServer struct {
	slog *zap.SugaredLogger
	// sms  *conf.SmsSection
	// cos  *conf.CosSection
	gcp *conf.GCPSection
	// dao  *dao.PgDao
	r   chi.Router
	url string
}

func NewRestServer(url string, slog *zap.SugaredLogger, gcp *conf.GCPSection) (s *RestServer) {
	s = &RestServer{
		slog: slog.With("service", "rest"),
		// sms:  sms,
		// cos:  cos,
		gcp: gcp,
		// dao:  dao.New(pgConfPtr, slog),
	}
	s.r = chi.NewRouter()
	s.registerRouter()
	s.url = url
	return s
}

func (s *RestServer) Run() {
	s.slog.Infof("rest server started on %s ...", s.url)
	if err := http.ListenAndServe(s.url, s.r); err != nil {
		s.slog.Errorf("rest server err %s", err.Error())
	}
}

func (s *RestServer) registerRouter() {

	// A good base middleware stack
	s.r.Use(middleware.RequestID)
	// s.r.Use(appMiddleware.WithWriteRes())
	s.r.Use(middleware.RealIP)
	s.r.Use(middleware.Logger)
	s.r.Use(middleware.Recoverer)
	s.r.Use(middleware.Timeout(60 * time.Second))
	s.r.Use(render.SetContentType(render.ContentTypeJSON))
	s.r.Use(cors.Handler(cors.Options{
		// AllowedOrigins:   []string{"http://localhost:5173"}, // Use this to allow specific origin hosts
		AllowedOrigins: []string{"https://*", "http://*"},
		// AllowOriginFunc:  func(r *http.Request, origin string) bool { return true },
		AllowedMethods:   []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
		AllowedHeaders:   []string{"X-PINGOTHER", "Accept", "Authorization", "Content-Type", "X-Access-Token", "X-CSRF-Token", util.MockIDKey, util.RequestIDKey},
		ExposedHeaders:   []string{"Link"},
		AllowCredentials: true,
		MaxAge:           300, // Maximum value not ignored by any of major browsers
	}))

	s.r.Get("/_ping", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("ok"))
	})

	nlpRouter := nlpRoute.New(routers.New(s))
	s.r.Mount(nlpRoute.PREFIX, nlpRouter.ChiRouter())

	// workwxRouter := workwxRoute.New(routers.New(s))
	// s.r.Mount(workwxRoute.PREFIX, workwxRouter.ChiRouter())

	// cliRouter := cliRoute.New(routers.New(s.slog, s.dao, s.sms, s.cos, s.vars))
	// s.r.Mount("/cli", cliRouter.ChiRouter())

	// s.r.Mount("/", frontend.FrontendHandler("/"))

}

/*** begin log.LoggerProxy ***/
func (s *RestServer) GetLogger() *zap.SugaredLogger {
	return s.slog
}

/*** begin conf.GCPProxy ***/
func (s *RestServer) GetEndPoint() string {
	return s.gcp.EndPoint
}

func (s *RestServer) GetAPIKey() string {
	return s.gcp.APIKey
}
